﻿//#define AUTO_LOGIN
using Circus.Utility;
using System;
using System.Collections.Generic;
using System.Data;
using System.Web;
using System.Linq;

namespace WoAiPao {

    /// <summary>
    /// 提供用户控制相关接口。
    /// </summary>
    public static class UserController {

        /// <summary>
        /// 使用指定的邮箱和密码登录。
        /// </summary>
        /// <param name="email">登录的邮箱。</param>
        /// <param name="password">登录的密码。</param>
        /// <param name="saveLoginCookie">指示是否将登录信息保存为 Cookie。</param>
        /// <returns>返回标准 JSON 字符串。</returns>
        public static UserLoginResult login(string email, string password, bool saveLoginCookie = false) {
            var user = DbBinder.select<User>("[email]=@0 OR [name]=@0", email);
            if (user == null) {
                return UserLoginResult.userNotFound;
            }

            if (Encryption.md5(password) != user.password) {
                return UserLoginResult.passwordError;
            }

            if (user.isDenied) {
                return UserLoginResult.denied;
            }

            onLogin(user, saveLoginCookie);

            return UserLoginResult.success;

        }

        /// <summary>
        /// 注销当前登录的用户。
        /// </summary>
        public static void logout() {
            HttpContext.Current.Session.Remove(userSessionName);
            HttpHelper.removeCookie(userPassportCookieName);
        }

        #region 内部实现

        /// <summary>
        /// 用于保存用户 ID 的 Cookie 名。
        /// </summary>
        private const string userIdCookieName = "fio_uid";

        /// <summary>
        /// 用于保存用户名的 Cookie 名。
        /// </summary>
        private const string userNameCookieName = "fio_uname";

        /// <summary>
        /// 用于保存用户登录通信证的 Cookie 名。
        /// </summary>
        private const string userPassportCookieName = "fio_ucard";

        /// <summary>
        /// 用于保存用户登录信息的 Cookie 所在的域。
        /// </summary>
        private const string cookieDomain = null;

        /// <summary>
        /// 用于保存用户登录信息的 Session 名。
        /// </summary>
        private const string userSessionName = "WoAiPao.UserController.currentUser";

        /// <summary>
        /// 判断当前用户是否已登录。
        /// </summary>
        public static bool isLogged {
            get {
                return checkLogin();
            }
        }

        /// <summary>
        /// 获取当前已登录的用户。如果用户未登录则尝试自动登录，如果仍然无法登录则报告错误。
        /// </summary>
        public static User currentUser {
            get {
                if (checkLogin()) {
                    return (User)HttpContext.Current.Session[userSessionName];
                }
                throw new InvalidOperationException("用户登录失效");
            }
            private set {
                HttpContext.Current.Session[userSessionName] = value;
            }
        }

        private static void onLogin(User user, bool saveLoginCookie) {

            currentUser = user;

            // 更新最后登录时间。
            user.lastLoginTime = DateTime.Now;
            user.lastLoginIp = ConvertHelper.ipToNumber(HttpHelper.getIP());
            DbBinder.update(user);

            // 保存登录信息。
            HttpHelper.setCookie(userIdCookieName, user.id.ToString(), 60 * 60 * 24 * 30).Domain = cookieDomain;
            HttpHelper.setCookie(userNameCookieName, user.name, 60 * 60 * 24 * 30).Domain = cookieDomain;

            // 保存自动登录信息。
            if (saveLoginCookie) {
                HttpHelper.setCookie(userPassportCookieName, Encryption.encryptAES(user.password), 60 * 60 * 24 * 30).Domain = cookieDomain;
            }

        }

        /// <summary>
        /// 检查用户登录状态并尝试自动登录。
        /// </summary>
        public static bool checkLogin() {

            // 已登录则不处理。
            if (HttpContext.Current.Session[userSessionName] != null) {
                return true;
            }

            // 自动登录。
            var ucard = HttpContext.Current.Request.Cookies[userPassportCookieName];
            if (ucard != null) {
                try {
                    var id = long.Parse(HttpContext.Current.Request.Cookies[userIdCookieName].Value);
                    var password = Encryption.decryptAES(HttpContext.Current.Request.Cookies[userPassportCookieName].Value);
                    var user = DbBinder.select<User>("[id]=@0 AND [password]=@1", id, password);
                    if (user != null && !user.isDenied) {
                        onLogin(user, true);
                        return true;
                    }
                } catch { }

            }

#if AUTO_LOGIN
            currentUser = new User() {
                id = 0,
                name = "<自动登录账号>",
                email = "<自动登录账号邮箱>"
            };

            return true;
#else
           return false;
#endif
        }

        private static void sendAuthMail(long userId, int authCode) {

        }

        #endregion

        public static void checkLogin(UserPermissions permissions) {
            if (currentUser.permissions.HasFlag(permissions)) {
                return;
            }

            Utility.showError("没有权限使用此功能");
        }

        /// <summary>
        /// 获取广告计划列表。
        /// </summary>
        /// <param name="pageNumber"></param>
        /// <param name="pageSize"></param>
        /// <param name="filter"></param>
        /// <param name="orderBy"></param>
        /// <param name="desc"></param>
        /// <returns></returns>
        public static List<User> getAllUsers(int pageNumber = 1, int pageSize = 20, string filter = null, string orderBy = null, bool desc = false) {

            // 支持排序。
            switch (orderBy) {
                case "name":
                    orderBy = "[name]";
                    break;
                case "lastLoginTime":
                    orderBy = "[lastLoginTime]";
                    break;
                case "createTime":
                    orderBy = "[DataChange_CreateTime]";
                    break;
                default:
                    orderBy = "[id]";
                    break;
            }

            if (desc) {
                orderBy += " DESC";
            }

            string where = null;
            object arg = null;
            if (filter != null) {
                where = "[name] LIKE @0";
                arg = "%" + filter + "%";
            }

            return DbBinder.selectAll<User>(pageNumber, pageSize, where, orderBy, arg == null ? null : new object[] { arg }).ToList();
        }

        public static void delete(long id) {

            if (!UserController.currentUser.permissions.HasFlag(UserPermissions.userManage)) {
                Utility.showError("权限不够");
                return;
            }

            if (UserController.currentUser.id == id) {
                Utility.showError("不能删除自己");
                return;
            }

            DbBinder.delete<User>(id);
            HttpContext.Current.Response.Redirect(HttpContext.Current.Request.UrlReferrer.ToString());
        }

        public static void setUserEnabled(long id, bool enabled) {

            if (!UserController.currentUser.permissions.HasFlag(UserPermissions.userManage)) {
                Utility.showError("权限不够");
                return;
            }

            if (UserController.currentUser.id == id) {
                Utility.showError("不能设置自己的状态");
                return;
            }

            var user = DbBinder.select<User>(id);
            user.isDenied = !enabled;
            DbBinder.update(user);

            HttpContext.Current.Response.Redirect(HttpContext.Current.Request.UrlReferrer.ToString());
        }

        public static User getUser(long id) {

            if (!UserController.currentUser.permissions.HasFlag(UserPermissions.userManage)) {
                return null;
            }

            var user = DbBinder.select<User>(id);
            if (user != null) {
                user.password = null;
            }
            return user;
        }

        /// <summary>
        /// 更新或插入一个广告计划。
        /// </summary>
        /// <param name="adPlan"></param>
        public static string saveUser(User user) {

            if (!UserController.currentUser.permissions.HasFlag(UserPermissions.userManage)) {
                return "没有权限";
            }

            if (String.IsNullOrWhiteSpace(user.name)) {
                return "用户名 不能为空";
            }

            if (DbBinder.select<User>("name=@0 AND id<>@1", user.name, user.id) != null) {
                return "用户名 " + user.name + " 已结被占用，无法使用";
            }

            if (!System.Text.RegularExpressions.Regex.IsMatch(user.name, @"^\w+$")) {
                return "用户名只能是汉字、字母或数字";
            }

            if (String.IsNullOrWhiteSpace(user.email)) {
                return "邮箱 不能为空";
            }

            if (!System.Text.RegularExpressions.Regex.IsMatch(user.email, @"^\w+@\w+(\.\w+)+$")) {
                return "邮箱格式不合法";
            }

            if (!String.IsNullOrWhiteSpace(user.password)) {
                user.password = Encryption.md5(user.password);
            } else {
                var uu = DbBinder.select<User>(user.id);
                if (uu != null) {
                    user.password = uu.password;
                } else {
                    return "密码 不能为空";
                }
            }

            // 不能更新自己的权限。
            if (user.id == currentUser.id && user.permissions != currentUser.permissions) {
                return "不能更新自己的权限";
            }

            DbBinder.updateOrInsert(user);
            return null;
        }

        /// <summary>
        /// 获取所有可用权限。
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<UserPermissions> getAllPermissions() {

            var cu = currentUser;
            var up = UserPermissions.FIRST_PERMISSION;

            for (; up < UserPermissions.LAST_PERMISSION; up = (UserPermissions)(((int)up) << 1)) {
                if (cu.permissions.HasFlag(up) && Enum.IsDefined(typeof(UserPermissions), up)) {
                    yield return up;
                }
            }

        }

    }

    /// <summary>
    /// 表示用户登录结果。
    /// </summary>
    public enum UserLoginResult {

        /// <summary>
        /// 登录成功。
        /// </summary>
        success,

        /// <summary>
        /// 用户名不存在。
        /// </summary>
        userNotFound,

        /// <summary>
        /// 密码错误。
        /// </summary>
        passwordError,

        /// <summary>
        /// 账号被封锁。
        /// </summary>
        denied,

        ///// <summary>
        ///// 账号未激活。
        ///// </summary>
        //notAcitived,

    }

}
